/*
 *  Arrow
 *
 *  Created by David Giovannini on 1/5/07.
 *  Copyright 2007 Software by Jove. All rights reserved.
 *
 */
 
#ifndef SBJ_Arrow_MessageHolder_h
#define SBJ_Arrow_MessageHolder_h

#include "SBJ/Arrow/IRouter.h"
#include "SBJ/Arrow/IPublisher.h"
#include "SBJ/Arrow/MessageHolderStats.h"
#include "SBJ/Container/NodeQueue.h"
#include "SBJ/Container/Array.h"
#include "SBJ/Interfaces/IExceptionObserver.h"
#include "SBJ/Thread/TaskDispatcher.h"

#include <boost/noncopyable.hpp>

#include <hash_map>
#include <vector>

namespace SBJ
{

namespace Arrow
{

class MessageHolder : public IRouter, public IPublisher, private boost::noncopyable
{
public:
	typedef boost::shared_ptr< MessageHolder > Ptr;
	typedef MessageHolderStats::Result Stats;
	
	MessageHolder( int numThreads = 1, const IExceptionObserver::Ptr& excObserver = IExceptionObserver::Ptr() );
	
	virtual ~MessageHolder( void );
	
	virtual Stats getStats( void ) const { return m_stats.getResults(); }
	
	virtual bool start( void );
	
	virtual bool stop( bool join = true );
	
	virtual bool addRouter( const IRouter::Ptr& router );
	
	virtual bool removeRouter( const IRouter::Ptr& router );
	
	virtual void addInterest( const Subscription& subscription );
	
	virtual void removeInterest( const Subscription& subscription );
	
	virtual void onMessage( Message& msg );
	
private:
	typedef NodeQueue< Message > MsgQueue;
	typedef stdext::hash_map< Topic, std::pair< int, MsgQueue* > > KeyedLists;
	
	class Submit
	{
	public:
		Submit( MsgQueue* queue, IRouter& router )
		: m_queue( queue )
		, m_router( router )
		{
		}
		
		void operator () ( void );
		
	private:
		MsgQueue* m_queue;
		IRouter& m_router;
	};
	
	void pushOutSubmittable( void );
	
	boost::mutex m_guard;
	IRouter::Ptr m_router;
	KeyedLists m_messages;
	TaskDispatcher< Submit > m_threadPool;
	volatile bool m_started;
	MessageHolderStats m_stats;
};

}

}

#endif
	